<template>
	<view class="gesture-back-wrapper"
		@touchstart="handleTouchStart"
		@touchmove="handleTouchMove" 
		@touchend="handleTouchEnd">
		
		<!-- 页面内容 -->
		<view class="page-content" :style="{ transform: `translateX(${translateX}px)` }">
			<slot></slot>
		</view>
		
		<!-- 遮罩层 -->
		<view 
			v-if="isDragging && translateX > 0" 
			class="mask"
			:style="{ opacity: maskOpacity }">
		</view>
	</view>
</template>

<script>
export default {
	name: 'GestureBack',
	props: {
		// 是否启用手势返回
		enabled: {
			type: Boolean,
			default: true
		},
		// 触发返回的最小滑动距离
		threshold: {
			type: Number,
			default: 80
		}
	},
	data() {
		return {
			isDragging: false,
			startX: 0,
			startY: 0,
			translateX: 0,
			maxTranslateX: 0,
			startTime: 0
		}
	},
	computed: {
		maskOpacity() {
			if (this.translateX <= 0) return 0;
			const ratio = this.translateX / this.maxTranslateX;
			return Math.min(0.3, ratio * 0.3);
		}
	},
	mounted() {
		// 获取屏幕宽度
		const systemInfo = uni.getSystemInfoSync();
		this.maxTranslateX = systemInfo.windowWidth * 0.8;
	},
	methods: {
		handleTouchStart(e) {
			if (!this.enabled) return;
			
			const touch = e.touches[0];
			this.startX = touch.clientX || touch.pageX;
			this.startY = touch.clientY || touch.pageY;
			this.startTime = Date.now();
			this.isDragging = false;
			
			// 只在屏幕左边缘区域内才开始监听
			const screenWidth = uni.getSystemInfoSync().windowWidth;
			if (this.startX > screenWidth * 0.15) {
				return;
			}
		},
		
		handleTouchMove(e) {
			if (!this.enabled) return;
			
			const touch = e.touches[0];
			const currentX = touch.clientX || touch.pageX;
			const currentY = touch.clientY || touch.pageY;
			const deltaX = currentX - this.startX;
			const deltaY = currentY - this.startY;
			
			// 判断是否为水平滑动
			if (Math.abs(deltaY) > Math.abs(deltaX) && Math.abs(deltaX) < 30) {
				return;
			}
			
			// 只处理向右滑动
			if (deltaX > 10 && !this.isDragging) {
				this.isDragging = true;
			}
			
			if (this.isDragging && deltaX > 0) {
				this.translateX = Math.min(deltaX, this.maxTranslateX);
				
				// 阻止默认行为
				if (e.preventDefault) e.preventDefault();
				if (e.stopPropagation) e.stopPropagation();
			}
		},
		
		handleTouchEnd(e) {
			if (!this.enabled || !this.isDragging) {
				this.resetPosition();
				return;
			}
			
			const duration = Date.now() - this.startTime;
			const velocity = this.translateX / (duration || 1);
			
			// 判断是否触发返回
			if (this.translateX >= this.threshold || (velocity > 0.3 && this.translateX > 30)) {
				this.triggerBack();
			} else {
				this.resetPosition();
			}
		},
		
		triggerBack() {
			this.translateX = this.maxTranslateX;
			
			setTimeout(() => {
				this.$emit('back');
				
				uni.navigateBack({
					delta: 1,
					fail: () => {
						uni.switchTab({
							url: '/pages/index/index'
						});
					}
				});
				
				this.resetPosition();
			}, 200);
		},
		
		resetPosition() {
			setTimeout(() => {
				this.isDragging = false;
				this.translateX = 0;
			}, 100);
		}
	}
}
</script>

<style lang="scss" scoped>
.gesture-back-wrapper {
	position: relative;
	width: 100%;
	height: 100%;
	overflow: hidden;
}

.page-content {
	width: 100%;
	height: 100%;
	transition: transform 0.25s ease-out;
	position: relative;
	z-index: 1;
	background-color: #fff;
}

.mask {
	position: fixed;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	background-color: #000;
	z-index: 999;
	pointer-events: none;
	transition: opacity 0.25s ease;
}
</style> 